package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.builder.ExhibitorFeign;
import com.eastfair.builder.dto.ExhibitorDTO;
import com.eastfair.builder.vo.ExhibitorVO;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.projectcore.enumeration.DataIsolationSystemSceneEnum;
import com.eastfair.venuebooking.api.ExhibitionFeign;
import com.eastfair.venuebooking.api.ExhibitionSpaceFeign;
import com.eastfair.venuebooking.enumeration.ResponsibilityerRoleEnum;
import com.eastfair.venuebooking.vo.ExhibitionSpaceVO;
import com.eastfair.venueservice.dao.ExhibitionManageMapper;
import com.eastfair.venueservice.dto.*;
import com.eastfair.venueservice.entity.*;
import com.eastfair.venueservice.enumeration.ExhibitionManageFinishStateEnum;
import com.eastfair.venueservice.enumeration.ServiceProviderTypeEnum;
import com.eastfair.venueservice.exceptioncode.VenueServiceExceptionCode;
import com.eastfair.venueservice.service.*;
import com.eastfair.venueservice.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 综合服务展会
 * </p>
 *
 * @author linan
 * @date 2022-07-15
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ExhibitionManageServiceImpl extends SuperServiceImpl<ExhibitionManageMapper, ExhibitionManage> implements ExhibitionManageService {

    public static final String ASCENDING = "ascending";
    @Resource
    private ExhibitionManageResponsibilityerService exhibitionManageResponsibilityerService;
    @Resource
    private ExhibitionServiceProviderService exhibitionServiceProviderService;
    @Resource
    private ServiceProviderSpaceService serviceProviderSpaceService;
    @Resource
    private ServicePriceListItemService servicePriceListItemService;
    @Resource
    private ServicePriceListService seriesPriceListService;
    @Resource
    private ServiceItemService serviceItemService;
    @Resource
    private ExhibitionSpaceFeign exhibitionSpaceFeign;
    @Resource
    private ExhibitionFeign exhibitionFeign;
    @Resource
    private ServiceProviderService serviceProviderService;

    @Resource
    private ExhibitionCompanyService exhibitionCompanyService;

    @Resource
    private VenueManageVenueReportService venueManageVenueReportService;

    @Resource
    private ServiceBookingService serviceBookingService;

    @Resource
    private VenueManageExhibitionSpaceService venueManageExhibitionSpaceService;

    @Resource
    private ExhibitorFeign exhibitorFeign;

    @Resource
    private VenueManageExhibitorService venueManageExhibitorService;

    @Resource
    private ExhibitionManageMapper exhibitionManageMapper;
    @Resource
    private BondManageService bondManageService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ExhibitionManage> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }
    @Override
    protected R<Boolean> handlerSave(ExhibitionManage model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }
    @Override
    protected R<Boolean> handlerUpdateById(ExhibitionManage model) {
        model.setSyncState(BusinessConstant.NO);
        return R.successDef();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> updateExhibitionManage(ExhibitionManageDTO exhibitionDTO) {
        // 获取修改前的数据
        ExhibitionManage exhibitionManageOld = getById(exhibitionDTO.getId());
        Long priceListId = exhibitionManageOld.getPriceListId();
        // 校验服务价目表是否被其他展会占用
        int count = count(new QueryWrapper<ExhibitionManage>().lambda().eq(ExhibitionManage::getPriceListId, exhibitionDTO.getPriceListId())
                .eq(ExhibitionManage::getIsDeleted, BusinessConstant.NO)
                .ne(ExhibitionManage::getId, exhibitionDTO.getId()));
        if(count>0){
            throw BizException.wrap(VenueServiceExceptionCode.EXHIBITION_PRICE_LIST_EXIST);
        }
        UpdateWrapper<ExhibitionManage> updateWrapper = new UpdateWrapper<>();
        packageUpdateWrapper(exhibitionDTO, updateWrapper);
        boolean b = update(updateWrapper);
        // 处理项目统筹
        // 处理项目协作
        saveResponsibilityer(exhibitionDTO);
        // 主场\主运信息 并同步服务
        saveExhibitionServiceProvider(exhibitionDTO,exhibitionManageOld);
        // 更新价目表展会数量
        seriesPriceListService.updateExhibitionNum(exhibitionDTO.getPriceListId(),1);
        // 原价目表展会数量改为0
        if(Objects.nonNull(priceListId) && !priceListId.equals(exhibitionDTO.getPriceListId())){
            seriesPriceListService.updateExhibitionNum(priceListId,0);
        }
        //判断服务商信息是否为空
        List<ExhibitionServiceProviderDTO> exhibitionServiceProviderList = exhibitionDTO.getExhibitionServiceProviderList();
        if( CollectionUtils.isNotEmpty(exhibitionServiceProviderList)){
            for (ExhibitionServiceProviderDTO exhibitionServiceProviderDTO: exhibitionServiceProviderList) {
                if(ServiceProviderTypeEnum.BUILD_SERVICE_PROVIDER.getCode().equals(exhibitionServiceProviderDTO.getServiceProviderType())) {
                    continue;
                }
                //通过服务商id获取保证金集合
                List<BondManageVO> list = bondManageService.getBondManageListByServiceProviderId(exhibitionServiceProviderDTO.getServiceProviderId());
                if(CollectionUtils.isNotEmpty(list)){
                    //通过服务商id删除设置保证金信息
                    bondManageService.delBondManageByServiceProviderId(exhibitionServiceProviderDTO.getServiceProviderId(), exhibitionDTO.getId());
                }

                //保存展会与主场主运配置时初始化保证金信息
                BondManageDTO bondManageDTO =new BondManageDTO();
                bondManageDTO.setExhibitionManageId(exhibitionDTO.getId());
                bondManageDTO.setExhibitionManageName(exhibitionDTO.getExhibitionName());
                bondManageDTO.setServiceProviderId(exhibitionServiceProviderDTO.getServiceProviderId());
                bondManageDTO.setServiceProviderName(exhibitionServiceProviderDTO.getServiceProviderName());
                bondManageDTO.setServiceProviderType(exhibitionServiceProviderDTO.getServiceProviderType());
                //获取系统标识
                bondManageDTO.setSystemScene(ContextUtil.getSystemScene());
                bondManageService.saveForVenue(bondManageDTO);
            }
        }
        return R.success(b);
    }

    @Override
    public R<IPage<ExhibitionManageVO>> queryExhibitionManage(PageParams<ExhibitionManageQuery> exhibitionManageQuery) {
        IPage<ExhibitionManageVO> resultPage  = new Page<>(exhibitionManageQuery.getCurrent(), exhibitionManageQuery.getSize());
        ExhibitionManageQuery model = exhibitionManageQuery.getModel();
        // 封装查询条件
        Map<Long, ExhibitionCompany> exhibitionCompanyMap = new HashMap<>(8);
        QueryWrapper<ExhibitionManage> queryWrapper = packageQueryWrapper(model,exhibitionManageQuery.getOrder(),exhibitionManageQuery.getSort(),exhibitionCompanyMap);
        Page<ExhibitionManage> page = exhibitionManageQuery.buildPage();
        // 分页查询
        page = page(page, queryWrapper);
        BeanUtils.copyProperties(page,resultPage);
        List<ExhibitionManage> records = page.getRecords();
        List<ExhibitionManageVO> exhibitionManageResult = new ArrayList<>();
        //  还需要赋值其他字段，不用ConvertUtil.convertList
        dealResultVO(records, exhibitionManageResult,model,exhibitionCompanyMap);
        resultPage.setRecords(exhibitionManageResult);
        return R.success(resultPage);
    }

    @Override
    public R<ExhibitionManageVO> queryExhibitionManageDetail(PageParams<ExhibitionManageQuery> exhibitionManageQuery) {
        R<IPage<ExhibitionManageVO>> iPageR = queryExhibitionManage(exhibitionManageQuery);
        List<ExhibitionManageVO> records = iPageR.getData().getRecords();
        if(CollectionUtils.isNotEmpty(records)){
            return R.success(records.get(0));
        }else {
            return R.fail(VenueServiceExceptionCode.EXHIBITION_NOT_EXIST);
        }
    }

    @Override
    public R<List<ExhibitionSpaceVO>> querySpaceByExhibitionManageId(ExhibitionManage exhibitionManage, Long serviceProviderId) {
        R<List<ExhibitionSpaceVO>> listR = exhibitionSpaceFeign.queryByExhibitionId(exhibitionManage.getVbExhibitionId());
        List<Long> spaceIds = baseMapper.queryServiceProviderSpaceId(exhibitionManage.getId(), serviceProviderId);
        List<ExhibitionSpaceVO> exhibitionSpaceVOS = listR.getData().stream().filter(e -> spaceIds.contains(e.getSpaceId())).collect(Collectors.toList());
        return R.success(exhibitionSpaceVOS);
    }

    @Override
    public List<ExhibitionSpaceSiteVO> querySpaceSiteByExhibitionManageId(Long exhibitionManageId) {
        log.info("querySpaceSiteByExhibitionManageId - 查询展会的展厅和展位, exhibitionManageId={}", exhibitionManageId);
        // 查询展会的展厅
        List<ExhibitionSpaceVO> exhibitionSpaceVOList = venueManageExhibitionSpaceService.listByExhibitionManageId(exhibitionManageId);
        if (exhibitionSpaceVOList == null || exhibitionSpaceVOList.isEmpty()) {
            return Collections.emptyList();
        }
        List<ExhibitionSpaceSiteVO> exhibitionSpaceSiteVOList = exhibitionSpaceVOList
                .stream()
                .map(exhibitionSpaceVO -> BeanUtil.toBean(exhibitionSpaceVO, ExhibitionSpaceSiteVO.class))
                .collect(Collectors.toList());
        // 查询展会的展位
        ExhibitorDTO exhibitorQuery = new ExhibitorDTO();
        exhibitorQuery.setExhibitionManageId(exhibitionManageId);
        List<ExhibitorVO> exhibitorVOList = venueManageExhibitorService.queryExhibitors(exhibitorQuery);
        if(exhibitorVOList == null || exhibitorVOList.isEmpty()) {
            return exhibitionSpaceSiteVOList;
        }
        // 封装展位到展厅
        Map<String, List<ExhibitorVO>> spaceSiteMap = exhibitorVOList
                .stream()
                .collect(Collectors.groupingBy(ExhibitorVO::getSpaceName));
        exhibitionSpaceSiteVOList.forEach(exhibitionSpaceSiteVO -> {
            List<ExhibitorVO> siteList = spaceSiteMap.get(exhibitionSpaceSiteVO.getSpaceName());
            if (siteList != null) {
                exhibitionSpaceSiteVO.setSiteList(siteList);
            }
        });
        return exhibitionSpaceSiteVOList;
    }

    @Override
    public Map<String, Object> queryExhibitionSummary(ExhibitionManage exhibitionManage) {
        Long exhibitionManageId = exhibitionManage.getId();
        HashMap<String, Object> map = new HashMap<>(4);
        // 基础信息
        HashMap<String, Object> basicData = new HashMap<>(4);
        packageBasicDate(exhibitionManage, exhibitionManageId, basicData);
        map.put("basicData",basicData);
        // 资金情况
        Map<String, Object> finance = new HashMap<>(2);
        List<ServiceBookingSimpleVO> serviceBookingVOS  = serviceBookingService.queryExhibitionFinance(exhibitionManageId);
        finance.put("list",serviceBookingVOS);
        if (CollectionUtils.isNotEmpty(serviceBookingVOS)) {
            finance.put("totalPrice",serviceBookingVOS.stream().map(ServiceBookingSimpleVO::getSubtotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add)) ;
        } else {
            finance.put("totalPrice",BigDecimal.ZERO) ;
        }
        map.put("finance",finance);
        // 报馆情况
        packageReportSpace(exhibitionManage, exhibitionManageId, map);
        // 服务预定排名
        List<ServiceBookingSimpleVO> bookingSimpleVOS = serviceBookingVOS.stream().sorted(Comparator.comparing(ServiceBookingSimpleVO::getBookingNum).reversed()).collect(Collectors.toList());
        bookingSimpleVOS = bookingSimpleVOS.subList(0, Math.min(bookingSimpleVOS.size(), 10));
        Map<String, Object> bookingRanking = new HashMap<>();
        bookingRanking.put("spaceName",bookingSimpleVOS.stream().map(ServiceBookingSimpleVO::getServiceName).collect(Collectors.toList()));
        bookingRanking.put("bookingNum",bookingSimpleVOS.stream().map(ServiceBookingSimpleVO::getBookingNum).collect(Collectors.toList()));
        map.put("bookingRanking",bookingRanking);
        // 服务库存预警
        List<ServiceBookingSimpleVO> warningRankingList  = serviceBookingService.queryWarningRanking();
        warningRankingList= warningRankingList.subList(0,Math.min(warningRankingList.size(), 10));
        Map<String, Object> warningRanking = new HashMap<>();
        warningRanking.put("serviceName",warningRankingList.stream().map(ServiceBookingSimpleVO::getServiceName).collect(Collectors.toList()));
        warningRanking.put("percent",warningRankingList.stream().map(ServiceBookingSimpleVO::getPercent).collect(Collectors.toList()));
        map.put("warningRanking",warningRanking);
        return map;
    }

    @Override
    public List<ExhibitionManageVO> queryNeedSyncExhibitionManage() {
        List<ExhibitionManage> list = list(new QueryWrapper<ExhibitionManage>().lambda().eq(ExhibitionManage::getSyncState, BusinessConstant.NO));
        List<ExhibitionManageVO> exhibitionManageVOS = new ArrayList<>(8);
        for (ExhibitionManage exhibitionManage : list) {
            ExhibitionManageVO exhibitionManageVO = BeanUtil.copyProperties(exhibitionManage, ExhibitionManageVO.class);
            exhibitionManageVOS.add(exhibitionManageVO);
        }
        return exhibitionManageVOS;
    }

    @Override
    public Page<ExhibitionManageVO> listLatestExhibition(PageParams<ExhibitionManageDTO> pageParams) {
        log.info("listLatestExhibition - 查询最近召开的展会列表, pageParams={}", pageParams);
        Page<ExhibitionManage> pageParam = pageParams.buildPage();
        Date now = new Date();
        DateTime beginDateTime = DateUtil.beginOfMonth(now);
        String beginDateString = beginDateTime.toDateStr();
        DateTime endDateTime = DateUtil.endOfMonth(now);
        String endDateString = endDateTime.toDateStr();
        QueryWrapper<ExhibitionManage> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("em.is_deleted", BusinessConstant.DELETE_NO)
                .and(StrUtil.isNotBlank(beginDateString) && StrUtil.isNotBlank(endDateString), dateQueryWrapper -> dateQueryWrapper
                        .between("em.arrangement_start_time", beginDateString, endDateString)
                        .or()
                        .between("em.arrangement_end_time", beginDateString, endDateString)
                        .or()
                        .between("em.exhibition_start_time", beginDateString, endDateString)
                        .or()
                        .between("em.exhibition_end_time", beginDateString, endDateString)
                        .or()
                        .between("em.dismantling_start_time", beginDateString, endDateString)
                        .or()
                        .between("em.dismantling_end_time", beginDateString, endDateString))
                .orderByDesc("em.arrangement_start_time")
        ;
        Page<ExhibitionManageVO> voPage = exhibitionManageMapper.listLatestExhibition(pageParam, queryWrapper);
        List<ExhibitionManageVO> voList = voPage.getRecords();
        if (voList == null || voList.isEmpty()) {
            return voPage;
        }
        // 查询场馆预定的场地，封装到展会中
        for (ExhibitionManageVO exhibitionManageVO : voList) {
            List<ExhibitionSpaceVO> exhibitionSpaceVoList = venueManageExhibitionSpaceService.listByExhibitionManageId(exhibitionManageVO.getId());
            exhibitionManageVO.setExhibitionSpaceList(exhibitionSpaceVoList);
        }
        return voPage;
    }

    @Override
    public Boolean syncCallback(List<Long> ids) {
        return update(new UpdateWrapper<ExhibitionManage>().lambda()
                .set(ExhibitionManage::getSyncState,BusinessConstant.YES)
                .in(ExhibitionManage::getId,ids));
    }

    /**
     * 报馆情况
     * @param exhibitionManage exhibitionManage
     * @param exhibitionManageId exhibitionManageId
     * @param map map
     */
    private void packageReportSpace(ExhibitionManage exhibitionManage, Long exhibitionManageId, HashMap<String, Object> map) {
        R<List<ExhibitionSpaceVO>> exhibitionSpaceVOS = exhibitionSpaceFeign.queryByExhibitionId(exhibitionManage.getVbExhibitionId());
        List<ReportVenueSpaceNumVO> result = new ArrayList<>();
        if(exhibitionSpaceVOS.getIsSuccess()){
            // 查询展会的所有展位
            ServiceProviderSpaceQuery serviceProviderSpaceQuery = new ServiceProviderSpaceQuery();
            serviceProviderSpaceQuery.setExhibitionManageId(exhibitionManageId);
            R<List<ExhibitorVO>> serviceProviderSite = exhibitorFeign.queryAllServiceProviderSite(serviceProviderSpaceQuery);
            if(serviceProviderSite.getIsSuccess()){
                List<ReportVenueSpaceNumVO>  reportVenueSpaceNum  =serviceBookingService.queryReportSpaceNum(exhibitionManageId);
                Map<String, Integer> reportVenueSpaceNumMap = reportVenueSpaceNum.stream().collect(Collectors.toMap(ReportVenueSpaceNumVO::getSpaceName, ReportVenueSpaceNumVO::getNum));
                Map<String, List<ExhibitorVO>> spaceSites = serviceProviderSite.getData().stream().collect(Collectors.groupingBy(ExhibitorVO::getSpaceName));
                for (ExhibitionSpaceVO exhibitionSpaceVO : exhibitionSpaceVOS.getData()) {
                    String spaceName = exhibitionSpaceVO.getSpaceName();
                    Integer reportSpaceNum = reportVenueSpaceNumMap.get(spaceName);
                    if(Objects.isNull(reportSpaceNum)){
                        reportSpaceNum = 0;
                    }
                    List<ExhibitorVO> exhibitorVOS = spaceSites.get(spaceName);
                    if(CollectionUtils.isEmpty(exhibitorVOS)){
                        exhibitorVOS = new ArrayList<>(0);
                    }
                    Integer percent = exhibitorVOS.size() == 0 ? 0 : reportSpaceNum * 100 / exhibitorVOS.size();
                    ReportVenueSpaceNumVO reportVenueSpaceNumVO = new ReportVenueSpaceNumVO();
                    reportVenueSpaceNumVO.setSpaceName(spaceName);
                    reportVenueSpaceNumVO.setPercent(percent);
                    result.add(reportVenueSpaceNumVO);
                }
            }
        }
        result.sort(Comparator.comparing(ReportVenueSpaceNumVO::getPercent));
        Collections.reverse(result);
        result =result.subList(0,Math.min(result.size(), 10));
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("spaceName",result.stream().map(ReportVenueSpaceNumVO::getSpaceName).collect(Collectors.toList()));
        resultMap.put("percent",result.stream().map(ReportVenueSpaceNumVO::getPercent).collect(Collectors.toList()));
        map.put("reportSpace",resultMap);
    }

    /**
     * 基础信息
     * @param exhibitionManage
     * @param exhibitionManageId
     * @param basicData
     */
    private void packageBasicDate(ExhibitionManage exhibitionManage, Long exhibitionManageId, HashMap<String, Object> basicData) {
        // 主办
        basicData.put("sponsorName", exhibitionManage.getSponsorName());
        // 展会项目
        R<String> projectName = exhibitionFeign.queryProjectName(exhibitionManage.getVbExhibitionId());
        if(projectName.getIsSuccess()){
            basicData.put("projectName",projectName.getData());
        }
        // 主场、主办
        List<ExhibitionServiceProvider> list = exhibitionServiceProviderService.list(new QueryWrapper<ExhibitionServiceProvider>().lambda()
                .eq(ExhibitionServiceProvider::getExhibitionManageId, exhibitionManageId)
                .eq(ExhibitionServiceProvider::getIsDeleted, BusinessConstant.NO));
        for (ExhibitionServiceProvider exhibitionServiceProvider : list) {
            String serviceProviderType = exhibitionServiceProvider.getServiceProviderType();
            if(ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER.getCode().equals(serviceProviderType)){
                basicData.put("home",exhibitionServiceProvider.getServiceProviderName());
            }else if(ServiceProviderTypeEnum.MAIN_TRANSPORT_SERVICE_PROVIDER.getCode().equals(serviceProviderType)){
                basicData.put("transport",exhibitionServiceProvider.getServiceProviderName());
            }
        }
    }


    @Override
    public R<ExhibitionManageVO> queryExhibitionManageByProvider(ExhibitionManageQuery exhibitionManageQuery) {
        log.info("queryExhibitionManageByProvider - 通过服务商查询进行中的展会, exhibitionManageQuery={}", exhibitionManageQuery);
        exhibitionManageQuery.setFinishState(ExhibitionManageFinishStateEnum.HAVE_IN_HAND);
        PageParams<ExhibitionManageQuery> queryPageParams = new PageParams<>();
        queryPageParams.setModel(exhibitionManageQuery);
        queryPageParams.setCurrent(1L);
        queryPageParams.setSize(1L);
        R<IPage<ExhibitionManageVO>> iPageR = queryExhibitionManage(queryPageParams);
        List<ExhibitionManageVO> records = iPageR.getData().getRecords();
        return R.success(CollectionUtils.isEmpty(records) ? null : records.get(0));
    }


    /**
     * 封装查询条件
     * @param model
     * @param order
     * @param sort
     * @return
     */
    private QueryWrapper<ExhibitionManage> packageQueryWrapper(ExhibitionManageQuery model, String order, String sort,Map<Long, ExhibitionCompany> exhibitionCompanyMap) {
        String systemScene = ContextUtil.getSystemScene();
        Set<Long> ids = new HashSet<>();
        if((DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode().equals(systemScene)
                || DataIsolationSystemSceneEnum.P_COMPOSITE_TRANSPORT.getCode().equals(systemScene)) && Objects.nonNull(model.getServiceProviderId())){
            // 如果是主场，需要特殊处理
            Long serviceProviderId = model.getServiceProviderId();
            List<ExhibitionServiceProvider> list = exhibitionServiceProviderService.list(new QueryWrapper<ExhibitionServiceProvider>().lambda()
                    .eq(ExhibitionServiceProvider::getServiceProviderId, serviceProviderId)
                    .eq(ExhibitionServiceProvider::getServiceProviderType, DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode().equals(systemScene)? ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER.getCode():ServiceProviderTypeEnum.MAIN_TRANSPORT_SERVICE_PROVIDER.getCode())
                    .eq(ExhibitionServiceProvider::getIsDeleted, BusinessConstant.NO));
            // 处理服务商-展会-展厅关系
            ids = getExhibitionManageIds(model, ids, list);
        }
        if((Objects.nonNull(model.getCompanyId()) ||Objects.nonNull(model.getSponsorPhone()))  && Objects.nonNull(model.getCompanyType()) ){
            List<ExhibitionCompany> list = exhibitionCompanyService.list(new QueryWrapper<ExhibitionCompany>().lambda()
                    .eq(Objects.nonNull(model.getCompanyId()),ExhibitionCompany::getId, model.getCompanyId())
                    .eq(Objects.nonNull(model.getSponsorPhone()),ExhibitionCompany::getPhone, model.getSponsorPhone())
                    .eq(ExhibitionCompany::getCompanyType, model.getCompanyType())
                    .eq(ExhibitionCompany::getIsDeleted, BusinessConstant.NO));
            if(CollectionUtils.isNotEmpty(list)){
                ids.addAll(list.stream().map(ExhibitionCompany::getExhibitionManageId).collect(Collectors.toSet()));
                exhibitionCompanyMap.putAll(list.stream().collect(Collectors.toMap(ExhibitionCompany::getExhibitionManageId, Function.identity())));
            }else {
                ids.add(0L);
            }
        }


        // 处理年份
        LocalDateTime thisYear = Objects.nonNull(model.getYear()) ? LocalDateTime.of(model.getYear(), 1, 1, 0, 0, 0, 0) : null;
        LocalDateTime afterYear = Objects.nonNull(model.getYear()) ? LocalDateTime.of(model.getYear() + 1, 1, 1, 0, 0, 0, 0) : null;
        LocalDateTime now = LocalDateTime.now();
        QueryWrapper<ExhibitionManage> queryWrapper = new QueryWrapper<ExhibitionManage>();
        queryWrapper.lambda()
                .eq(ExhibitionManage::getIsDeleted, BusinessConstant.NO)
                .eq(!DataIsolationSystemSceneEnum.P_COMPOSITE_VENUE.getCode().equals(ContextUtil.getSystemScene()),ExhibitionManage::getIsEnabled, BusinessConstant.YES)
                .eq(Objects.nonNull(model.getId()), ExhibitionManage::getId, model.getId())
                .in(CollectionUtils.isNotEmpty(ids), ExhibitionManage::getId, ids)
                .like(StringUtils.isNotBlank(model.getExhibitionName()), ExhibitionManage::getExhibitionName, model.getExhibitionName())
                .eq(Objects.nonNull(model.getIndustry()), ExhibitionManage::getIndustry, model.getIndustry())
                .eq(Objects.nonNull(model.getExhibitionType()), ExhibitionManage::getExhibitionType, model.getExhibitionType())
                .and(Objects.nonNull(model.getArrangementStartTime()) && Objects.nonNull(model.getDismantlingEndTime())
                        ,e->e.or(f->f.le(ExhibitionManage::getArrangementStartTime, model.getArrangementStartTime()).ge(ExhibitionManage::getDismantlingEndTime, model.getArrangementStartTime()))
                                .or(f->f.le(ExhibitionManage::getArrangementStartTime, model.getDismantlingEndTime()).ge(ExhibitionManage::getDismantlingEndTime, model.getDismantlingEndTime()))
                                .or(f->f.ge(ExhibitionManage::getArrangementStartTime, model.getArrangementStartTime()).le(ExhibitionManage::getDismantlingEndTime, model.getDismantlingEndTime()))
                )
                // 是否是进行中
                .le(Objects.nonNull(model.getFinishState()) && ExhibitionManageFinishStateEnum.HAVE_IN_HAND.eq(model.getFinishState()),ExhibitionManage::getArrangementStartTime,now)
                .ge(Objects.nonNull(model.getFinishState()) && ExhibitionManageFinishStateEnum.HAVE_IN_HAND.eq(model.getFinishState()),ExhibitionManage::getDismantlingEndTime,now)
                // 是否未结束
                .ge(Objects.nonNull(model.getFinishState()) && ExhibitionManageFinishStateEnum.NOT_COMPLETED.eq(model.getFinishState()),ExhibitionManage::getDismantlingEndTime,now)
                .and(Objects.nonNull(model.getYear()),
                        e -> e.or(f -> f.ge(ExhibitionManage::getArrangementStartTime, thisYear).lt(ExhibitionManage::getArrangementStartTime, afterYear))
                                .or(f -> f.ge(ExhibitionManage::getDismantlingEndTime, thisYear).lt(ExhibitionManage::getDismantlingEndTime, afterYear))
                                .or(f -> f.lt(ExhibitionManage::getArrangementStartTime, thisYear).ge(ExhibitionManage::getDismantlingEndTime, afterYear)));
        // 又从罗挺提的"离得近" 改成业主提的倒叙
        queryWrapper.orderByDesc("arrangement_start_time");
        return queryWrapper;
    }

    private Set<Long> getExhibitionManageIds(ExhibitionManageQuery model, Set<Long> ids, List<ExhibitionServiceProvider> list) {
        if(CollectionUtils.isNotEmpty(list) && CollectionUtils.isNotEmpty(model.getExhibitionSpaceList())){
            for (ExhibitionServiceProvider exhibitionServiceProvider : list) {
                // 查询服务商展厅
                Long serviceProviderId = exhibitionServiceProvider.getServiceProviderId();
                Long exhibitionManageId = exhibitionServiceProvider.getExhibitionManageId();
                List<ServiceProviderSpaceVO> serviceProviderSpaceVOS = serviceProviderSpaceService.queryByExhibitionId(exhibitionManageId, serviceProviderId);
                // 传入的条件
                Set<String> spaceNames = model.getExhibitionSpaceList().stream().map(ExhibitionSpaceVO::getSpaceName).collect(Collectors.toSet());
                // 服务商的展厅
                Set<String> spaceNameCompare = serviceProviderSpaceVOS.stream().map(ServiceProviderSpaceVO::getSpaceName).collect(Collectors.toSet());
                boolean addOrNot = true;
                for (String spaceName : spaceNames) {
                    // 如果返回结果不满足查询的展厅，则不添加该展会
                    if(!spaceNameCompare.contains(spaceName)){
                        addOrNot=false;
                        break;
                    }
                }
                if(addOrNot){
                    ids.add(exhibitionManageId);
                }
            }
        }else {
            ids = list.stream().map(ExhibitionServiceProvider::getExhibitionManageId).collect(Collectors.toSet());
        }
        if(CollectionUtils.isEmpty(ids)){
            ids.add(0L);
        }
        return ids;
    }

    @Override
    public R<List<ExhibitionManageVO>> queryAllExhibitionManage(ExhibitionManageQuery exhibitionManageQuery) {
        String systemScene = ContextUtil.getSystemScene();
        List<Long> ids = new ArrayList<>();
        if ((DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode().equals(systemScene) || DataIsolationSystemSceneEnum.P_COMPOSITE_TRANSPORT.getCode().equals(systemScene)) && Objects.nonNull(exhibitionManageQuery.getServiceProviderId())) {
            // 如果是主场，需要特殊处理
            Long serviceProviderId = exhibitionManageQuery.getServiceProviderId();
            List<ExhibitionServiceProvider> list = exhibitionServiceProviderService.list(new QueryWrapper<ExhibitionServiceProvider>().lambda()
                    .eq(ExhibitionServiceProvider::getServiceProviderId, serviceProviderId)
                    .eq(ExhibitionServiceProvider::getServiceProviderType, DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode().equals(systemScene)? ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER.getCode():ServiceProviderTypeEnum.MAIN_TRANSPORT_SERVICE_PROVIDER.getCode())
                    .eq(ExhibitionServiceProvider::getIsDeleted, BusinessConstant.NO));
            ids = list.stream().map(ExhibitionServiceProvider::getExhibitionManageId).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(ids)){
                ids.add(0L);
            }
        }
        List<ExhibitionManage> list = list(new QueryWrapper<ExhibitionManage>()
                .lambda()
                .like(StringUtils.isNotBlank(exhibitionManageQuery.getExhibitionName()),ExhibitionManage::getExhibitionName,exhibitionManageQuery.getExhibitionName())
                .in(CollectionUtils.isNotEmpty(exhibitionManageQuery.getIds()),ExhibitionManage::getId,exhibitionManageQuery.getIds())
                .in(CollectionUtils.isNotEmpty(ids), ExhibitionManage::getId, ids)
                .eq(!DataIsolationSystemSceneEnum.P_COMPOSITE_VENUE.getCode().equals(ContextUtil.getSystemScene()),ExhibitionManage::getIsEnabled, BusinessConstant.YES)
                .eq(ExhibitionManage::getIsDeleted,BusinessConstant.NO));
        return R.success(ConvertUtil.convertList(list,ExhibitionManageVO.class));
    }

    /**
     * 处理返回结果VO
     * @param records records
     * @param exhibitionManageResult exhibitionManageResult
     * @param model
     * @param exhibitionCompanyMap
     */
    private void dealResultVO(List<ExhibitionManage> records, List<ExhibitionManageVO> exhibitionManageResult, ExhibitionManageQuery model, Map<Long, ExhibitionCompany> exhibitionCompanyMap) {
        for (ExhibitionManage record : records) {
            ExhibitionManageVO exhibitionManageVO = BeanUtil.copyProperties(record, ExhibitionManageVO.class);
            // 主要负责人 协助人员
            QueryWrapper<ExhibitionManageResponsibilityer> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(ExhibitionManageResponsibilityer::getIsDeleted, BusinessConstant.NO).eq(ExhibitionManageResponsibilityer::getExhibitionManageId,record.getId());
            List<ExhibitionManageResponsibilityer> exhibitionResponsibilityerList = exhibitionManageResponsibilityerService.list(wrapper);
            // 主要负责人
            List<ExhibitionManageResponsibilityer> projectCoordinatorList = exhibitionResponsibilityerList.stream().filter(e -> e.getResponsibilityerRole().eq(ResponsibilityerRoleEnum.MAIN_IN_CHARGE)).map(e->e.setResponsibilityerRole(ResponsibilityerRoleEnum.MAIN_IN_CHARGE)).collect(Collectors.toList());
            exhibitionManageVO.setProjectCoordinatorList(ConvertUtil.convertList(projectCoordinatorList, ExhibitionManageResponsibilityerVO.class));
            // 协助人员
            List<ExhibitionManageResponsibilityer> projectCollaborationList = exhibitionResponsibilityerList.stream().filter(e -> e.getResponsibilityerRole().eq(ResponsibilityerRoleEnum.ASSISTING_STAFF )).map(e->e.setResponsibilityerRole(ResponsibilityerRoleEnum.ASSISTING_STAFF)).collect(Collectors.toList());
            exhibitionManageVO.setProjectCollaborationList(ConvertUtil.convertList(projectCollaborationList, ExhibitionManageResponsibilityerVO.class));
            // 展会展厅信息
            Map<String, String> spaceMap = new HashMap<>(16);
            if(Objects.nonNull(model.getId()) || Objects.nonNull(model.getServiceProviderId())){
                R<List<ExhibitionSpaceVO>> listR = exhibitionSpaceFeign.queryByExhibitionId(record.getVbExhibitionId());
                List<ExhibitionSpaceVO> exhibitionSpaceVOList = listR.getData();
                exhibitionManageVO.setExhibitionSpaceList(exhibitionSpaceVOList);
                exhibitionSpaceVOList.forEach(exhibitionSpaceVO -> spaceMap.put(exhibitionSpaceVO.getSpaceCode(), exhibitionSpaceVO.getSpaceName()));
            }
            // 主场\主运信息
            List<ExhibitionServiceProvider> list = exhibitionServiceProviderService.list(new QueryWrapper<ExhibitionServiceProvider>().lambda()
                    .eq(ExhibitionServiceProvider::getExhibitionManageId, record.getId())
                            .in(ExhibitionServiceProvider::getServiceProviderType,Arrays.asList(ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER,ServiceProviderTypeEnum.MAIN_TRANSPORT_SERVICE_PROVIDER))
                    .eq(ExhibitionServiceProvider::getIsDeleted, BusinessConstant.NO));
            List<ExhibitionServiceProviderVO> exhibitionServiceProviderList = new ArrayList<>();
            for (ExhibitionServiceProvider exhibitionServiceProvider : list) {
                ServiceProvider provider = serviceProviderService.getById(exhibitionServiceProvider.getServiceProviderId());
                ExhibitionServiceProviderVO exhibitionServiceProviderVO = BeanUtil.copyProperties(exhibitionServiceProvider, ExhibitionServiceProviderVO.class);
                // 服务商名称
                exhibitionServiceProviderVO.setServiceProviderName(Objects.nonNull(provider)?provider.getCompanyName(): Strings.EMPTY);
                // 使用展厅
                List<ServiceProviderSpace> serviceProviderSpaceList = serviceProviderSpaceService
                        .list(new QueryWrapper<ServiceProviderSpace>()
                                .lambda()
                                .eq(ServiceProviderSpace::getExhibitionServiceProviderId, exhibitionServiceProviderVO.getId())
                                .eq(ServiceProviderSpace::getIsDeleted, BusinessConstant.NO));
                List<ServiceProviderSpaceVO> serviceProviderSpaceVOList = ConvertUtil.convertList(serviceProviderSpaceList, ServiceProviderSpaceVO.class);
                serviceProviderSpaceVOList.forEach(serviceProviderSpaceVO -> {
                    String spaceName = spaceMap.get(serviceProviderSpaceVO.getSpaceCode());
                    serviceProviderSpaceVO.setSpaceName(spaceName);
                });
                exhibitionServiceProviderVO.setServiceProviderSpaceList(serviceProviderSpaceVOList);
                exhibitionServiceProviderList.add(exhibitionServiceProviderVO);
            }
            // 展会完成状态
            LocalDateTime now = LocalDateTime.now();
            if(now.isBefore(record.getArrangementStartTime())){
                // 小于布展时间 未开始
                exhibitionManageVO.setFinishStateCode(ExhibitionManageFinishStateEnum.NOT_STARTED.getCode());
                exhibitionManageVO.setFinishStateName(ExhibitionManageFinishStateEnum.NOT_STARTED.getDesc());
            }else if(now.isAfter(record.getDismantlingEndTime())){
                // 大于撤展时间 已结束
                exhibitionManageVO.setFinishStateCode(ExhibitionManageFinishStateEnum.COMPLETED.getCode());
                exhibitionManageVO.setFinishStateName(ExhibitionManageFinishStateEnum.COMPLETED.getDesc());
            }else {
                exhibitionManageVO.setFinishStateCode(ExhibitionManageFinishStateEnum.HAVE_IN_HAND.getCode());
                exhibitionManageVO.setFinishStateName(ExhibitionManageFinishStateEnum.HAVE_IN_HAND.getDesc());
            }
            exhibitionManageVO.setExhibitionServiceProviderList(exhibitionServiceProviderList);
            // 主办id
            ExhibitionCompany exhibitionCompany = exhibitionCompanyMap.get(record.getId());
            if(Objects.nonNull(exhibitionCompany)){
                exhibitionManageVO.setCompanyId(exhibitionCompany.getId());
            }
            exhibitionManageResult.add(exhibitionManageVO);
        }
    }

    /**
     * 保存展会主场\主运信息
     * @param exhibitionDTO
     * @param exhibitionManageOld
     */
    private void saveExhibitionServiceProvider(ExhibitionManageDTO exhibitionDTO, ExhibitionManage exhibitionManageOld) {
        // 查询现在的展会服务商绑定关系
        List<ExhibitionServiceProvider> existExhibitionServiceProviderList = exhibitionServiceProviderService.listByExhibitionManageId(exhibitionDTO.getId()).stream().filter(e->e.getServiceProviderType().equals(ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER.getCode()) || e.getServiceProviderType().equals(ServiceProviderTypeEnum.MAIN_TRANSPORT_SERVICE_PROVIDER.getCode())).collect(Collectors.toList());
        // 删除现在的展会服务商绑定关系
        exhibitionServiceProviderService.removeByIdsOfLogic(existExhibitionServiceProviderList);
        // 删除现在的服务商展厅关系
        List<Long> exhibitionServiceProviderIdList = existExhibitionServiceProviderList
                .stream()
                .map(ExhibitionServiceProvider::getId)
                .collect(Collectors.toList());
        serviceProviderSpaceService.removeBatchByExhibitionServiceProviderId(exhibitionServiceProviderIdList);
        // 插入新的展会服务商关系，服务商展厅关系
        List<ExhibitionServiceProviderDTO> exhibitionServiceProviderDTOList = exhibitionDTO.getExhibitionServiceProviderList();
        exhibitionServiceProviderService.saveBatch(exhibitionServiceProviderDTOList, exhibitionDTO.getId());
        // 保存展会企业关系
        if (exhibitionServiceProviderDTOList != null && !exhibitionServiceProviderDTOList.isEmpty()) {
            List<Long> serviceProviderIds = exhibitionServiceProviderDTOList
                    .stream()
                    .map(ExhibitionServiceProviderDTO::getServiceProviderId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if (!serviceProviderIds.isEmpty()) {
                List<ServiceProviderVO> serviceProviderVOList = serviceProviderService.listServiceProviderByIds(serviceProviderIds);
                exhibitionCompanyService.saveBatchByHomeOrMainTransport(serviceProviderVOList, exhibitionDTO.getId());
            }
        }
        // 保存主场报馆记录
        venueManageVenueReportService.saveBatchByExhibitionManage(exhibitionDTO);
        // 同步服务
        // syncServiceItem(exhibitionDTO, exhibitionManageOld);
    }

    /**
     * 同步服务
     * @param exhibitionDTO
     * @param exhibitionManageOld
     */
    private void syncServiceItem(ExhibitionManageDTO exhibitionDTO, ExhibitionManage exhibitionManageOld) {
        if(Objects.nonNull(exhibitionDTO.getPriceListId())
                && Objects.nonNull(exhibitionManageOld.getPriceListId())
                && exhibitionDTO.getPriceListId().equals(exhibitionManageOld.getPriceListId())){
            log.info("未对展会价目绑定关系进行修改");
        }else {
            if(Objects.nonNull(exhibitionDTO.getPriceListId())){
                // 先删除原来同步过的服务
                serviceItemService.removeByExhibition(exhibitionDTO.getId(), Arrays.asList(DataIsolationSystemSceneEnum.P_COMPOSITE_COURT,DataIsolationSystemSceneEnum.P_COMPOSITE_TRANSPORT));
                // 同步主场/主运服务
                R<ServicePriceListVO> servicePriceListVOR = servicePriceListItemService.queryPriceListByExhibition(ServicePriceListQuery.builder().exhibitionManageId(exhibitionDTO.getId()).build());
                ServicePriceListVO data = servicePriceListVOR.getData();
                if(Objects.nonNull(data)){
                    serviceItemService.syncServiceItem(exhibitionDTO.getId(),data,DataIsolationSystemSceneEnum.P_COMPOSITE_COURT,null);
                    serviceItemService.syncServiceItem(exhibitionDTO.getId(),data,DataIsolationSystemSceneEnum.P_COMPOSITE_TRANSPORT,null);
                }
            }
        }
    }

    /**
     * 插入新的关系
     * @param exhibitionDTO exhibitionDTO
     */
    private void saveResponsibilityer(ExhibitionManageDTO exhibitionDTO) {
        List<ExhibitionManageResponsibilityerDTO> projectCoordinatorList = exhibitionDTO.getProjectCoordinatorList();
        List<ExhibitionManageResponsibilityerDTO> projectCollaborationList = exhibitionDTO.getProjectCollaborationList();
        // 先软删历史绑定关系
        exhibitionManageResponsibilityerService.removeByExhibitionManageId(exhibitionDTO.getId());
        // 插入新的关系
        if (CollectionUtils.isNotEmpty(projectCoordinatorList)) {
            // 处理项目统筹
            for (ExhibitionManageResponsibilityerDTO exhibitionManageResponsibilityerDTO : projectCoordinatorList) {
                ExhibitionManageResponsibilityer manageResponsibilityer = BeanUtil.copyProperties(exhibitionManageResponsibilityerDTO, ExhibitionManageResponsibilityer.class,"id");
                manageResponsibilityer.setResponsibilityerRole(ResponsibilityerRoleEnum.MAIN_IN_CHARGE);
                manageResponsibilityer.setExhibitionManageId(exhibitionDTO.getId());
                exhibitionManageResponsibilityerService.save(manageResponsibilityer);
            }
        }
        if (CollectionUtils.isNotEmpty(projectCollaborationList)) {
            // 处理项目协作
            for (ExhibitionManageResponsibilityerDTO exhibitionManageResponsibilityerDTO : projectCollaborationList) {
                ExhibitionManageResponsibilityer manageResponsibilityer = BeanUtil.copyProperties(exhibitionManageResponsibilityerDTO, ExhibitionManageResponsibilityer.class,"id");
                manageResponsibilityer.setResponsibilityerRole(ResponsibilityerRoleEnum.ASSISTING_STAFF);
                manageResponsibilityer.setExhibitionManageId(exhibitionDTO.getId());
                exhibitionManageResponsibilityerService.save(manageResponsibilityer);
            }
        }
    }

    /**
     * 拼装更新参数
     * @param exhibitionDTO exhibitionDTO
     * @param updateWrapper updateWrapper
     */
    private void packageUpdateWrapper(ExhibitionManageDTO exhibitionDTO, UpdateWrapper<ExhibitionManage> updateWrapper) {
        updateWrapper.lambda()
                .eq(ExhibitionManage::getId, exhibitionDTO.getId())
                .set(ExhibitionManage::getIsEnabled, BusinessConstant.YES)
                .set(ExhibitionManage::getSyncState, BusinessConstant.NO)
                // 主办单位
                .set(ExhibitionManage::getSponsorName, exhibitionDTO.getSponsorName())
                // 展会类型
                .set(ExhibitionManage::getExhibitionType, exhibitionDTO.getExhibitionType())
                // 使用面积
                .set(ExhibitionManage::getReserveArea, exhibitionDTO.getReserveArea())
                // 行业属性
                .set(ExhibitionManage::getIndustry, exhibitionDTO.getIndustry())
                // 展前折扣时间
                .set(Objects.nonNull(exhibitionDTO.getPreDiscountStartTime()), ExhibitionManage::getPreDiscountStartTime, exhibitionDTO.getPreDiscountStartTime())
                .set(Objects.nonNull(exhibitionDTO.getPreDiscountEndTime()), ExhibitionManage::getPreDiscountEndTime, exhibitionDTO.getPreDiscountEndTime())
                // 现场折扣时间
                .set(Objects.nonNull(exhibitionDTO.getOnDiscountStartTime()), ExhibitionManage::getOnDiscountStartTime, exhibitionDTO.getOnDiscountStartTime())
                .set(Objects.nonNull(exhibitionDTO.getOnDiscountEndTime()), ExhibitionManage::getOnDiscountEndTime, exhibitionDTO.getOnDiscountEndTime())
                // 价目
                .set(Objects.nonNull(exhibitionDTO.getPriceListId()), ExhibitionManage::getPriceListId, exhibitionDTO.getPriceListId());

    }
}
